
//
// 130322 - AH - Created.
//

package org.japril.swing.jutil.logging;

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.io.IOException;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListSelectionModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import org.japril.swing.TestFrame;
import org.japril.swing.jutil.logging.ControlLogSinks.ControlLogSinkManager;

/**
 * <p>
 *   View for end user to manage 
 *   {@link ControlLogSinks}.
 * </p>
 * @author Arne Halvorsen (AH)
 */
@SuppressWarnings("serial")
public final class ControlLogSinksPanel extends JPanel
{
  private final DefaultListModel m_model=new DefaultListModel();
  
  private final JList m_list=new JList(m_model);
  
  /**
   * <p>
   *   Constructor.
   * </p>
   * @param actions Client provided actions to add to button 'bar' {@code this}
   *                has, may be none given or {@code null}. Elements that are
   *                {@code null} is ignored.
   */
  public ControlLogSinksPanel(Action... actions)
  {
    m_list.getSelectionModel().setSelectionMode(
      ListSelectionModel.SINGLE_SELECTION);
    setLayout(new BorderLayout());
    add(new JScrollPane(m_list), BorderLayout.CENTER);
    
    m_list.addListSelectionListener
    (
      new ListSelectionListener()
      {
        public void valueChanged(ListSelectionEvent e)
        {
          Object s=m_list.getSelectedValue();
          if (s instanceof ControlLogSinkManager)
          {
            m_deleteAction.setEnabled(true);
            m_useAction.setEnabled(true);
          }
          else
          {
            m_deleteAction.setEnabled(false);
            m_useAction.setEnabled(false);
          }
        }
      }
    );
    
    JPanel buttons=new JPanel(new FlowLayout(FlowLayout.CENTER));
    buttons.add(new JButton(m_createAction));
    buttons.add(new JButton(m_useAction));
    buttons.add(new JButton(m_saveAction));
    buttons.add(new JButton(m_deleteAction));
    add(buttons, BorderLayout.SOUTH);
    
    if (actions!=null)
    {
      for (Action action : actions)
      {
        if (action!=null) buttons.add(new JButton(action));  
      }
    }
    
    update();
    
    ControlLogSinks.getInstance().addChangeListener
    (
      new ChangeListener()
      {
        public void stateChanged(ChangeEvent e){ update(); }
      }
    );
    
  }
  
  /**
   * <p>
   *   Adds
   *   {@link ListSelectionListener}.
   * </p>
   * @param lsl Listener to add.
   */
  public void addListSelectionListener(ListSelectionListener lsl)
  {
    if (lsl==null)
    {
      throw new NullPointerException("lsl");
    }
    
    m_list.addListSelectionListener(lsl);
  }
  
  /**
   * <p>
   *   Removes
   *   {@link ListSelectionListener}.
   * </p>
   * @param lsl Listener to add.
   */
  public void removeListSelectionListener(ListSelectionListener lsl)
  {
    if (lsl==null)
    {
      throw new NullPointerException("lsl");
    }
    
    m_list.removeListSelectionListener(lsl);
  }
  
  private final Action m_createAction=new AbstractAction("Create")
  {  
    public void actionPerformed(ActionEvent e)
    {
      try
      {
        ControlLogSinks sinks=ControlLogSinks.getInstance();
        String name=JOptionPane.showInputDialog("Name?");
        name=(name==null) ? "" : name.trim();
        if (name.length()>0)
        {
          if (sinks.exists(name))
          {
            JOptionPane.showMessageDialog(ControlLogSinksPanel.this,
              "Name exists", "Input Error", JOptionPane.INFORMATION_MESSAGE);  
          }
          else
          {
            sinks.create(name);
          }
        }
      }
      catch (IOException iox)
      {
        iox.printStackTrace();
      }
    }
  };
  
  private final Action m_saveAction=new AbstractAction("Save")
  {
    public void actionPerformed(ActionEvent e)
    {
      try
      {
        ControlLogSinks sinks=ControlLogSinks.getInstance();
        sinks.save();
      }
      catch (IOException iox)
      {
        iox.printStackTrace();
      }
    }
    
  };
  
  private final Action m_deleteAction=new AbstractAction("Delete")
  {
    {
      setEnabled(false);
    }
    public void actionPerformed(ActionEvent e)
    {
      Object s=m_list.getSelectedValue();
      if (s instanceof ControlLogSinkManager)
      {
        ControlLogSinkManager m=(ControlLogSinkManager)s;
        ControlLogSinks sinks=ControlLogSinks.getInstance();
        sinks.delete(m);
      }
    }
  };
  
  private final Action m_useAction=new AbstractAction("Use")
  {
    {
      setEnabled(false);
    }
    public void actionPerformed(ActionEvent e)
    {
      Object s=m_list.getSelectedValue();
      if (s instanceof ControlLogSinkManager)
      {
        ControlLogSinkManager m=(ControlLogSinkManager)s;
        ControlLogSinks sinks=ControlLogSinks.getInstance();
        sinks.setCurrent(m);
      }
    }
  };
  
  private void update()
  {
    m_model.removeAllElements();
    ControlLogSinks sinks=ControlLogSinks.getInstance();
    for (ControlLogSinkManager m : sinks) m_model.addElement(m);
  }
  
  public static void main(String[] args) 
  {
    TestFrame.show(new ControlLogSinksPanel());  
  }
  
}
